package com.example.a1.fannong.core.app;

import android.app.ActivityManager;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.view.View;

import com.example.a1.fannong.core.manager.setting.SettingManager;
import com.example.a1.fannong.core.manager.user.UserManager;
import com.example.a1.fannong.core.manager.version.VersionManager;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.personal.library.imageloader.ImageLoader;


/**
 * 程序 应用上下文
 */
public class MyApplication extends Application {
    public static final Handler HANDLER = new Handler();
    private static MyApplication application;
    private HashMap<String, BaseManager> managers = new HashMap<>();
    private Handler handler = new Handler();

    public static MyApplication getInstance() {
        return application;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        application = this;

        ImageLoader.getInstance().init(this);

        String pidName = getUIPName();
        if (pidName.equals(getPackageName())) {
            // 初始化管理器
            initManager();
        }
        startService(new Intent(this, MainService.class));
    }

    @NonNull
    private String getUIPName() {
        int pid = android.os.Process.myPid();
        ActivityManager mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        for (ActivityManager.RunningAppProcessInfo appProcess : mActivityManager.getRunningAppProcesses()) {
            if (appProcess.pid == pid) {
                return appProcess.processName;
            }
        }
        return "";
    }

    private void initManager() {
        List<BaseManager> managerList = new ArrayList<>();
        registerManager(managerList);
        for (BaseManager baseManager : managerList) {
            injectManager(baseManager);
            baseManager.onManagerCreate(this);
            managers.put(baseManager.getClass().getName(), baseManager);
        }

        for (Map.Entry<String, BaseManager> entry : managers.entrySet()) {
            entry.getValue().onAllManagerCreated();
        }
    }

    public <V extends BaseManager> V getManager(Class<V> cls) {
        return (V) managers.get(cls.getName());
    }

    public void injectManager(Object object) {
        Class<?> aClass = object.getClass();

        while (aClass != Object.class && aClass != View.class && aClass != BaseManager.class && aClass != BaseActivity.class) {
            Field[] declaredFields = aClass.getDeclaredFields();
            if (declaredFields != null && declaredFields.length > 0) {
                for (Field field : declaredFields) {
                    int modifiers = field.getModifiers();
                    if (Modifier.isFinal(modifiers) || Modifier.isStatic(modifiers)) {
                        // 忽略掉static 和 final 修饰的变量
                        continue;
                    }

                    if (!field.isAnnotationPresent(Manager.class)) {
                        continue;
                    }

                    Class<?> type = field.getType();
                    if (!BaseManager.class.isAssignableFrom(type)) {
                        throw new RuntimeException("@Manager 注解只能应用到BaseManager的子类");
                    }

                    BaseManager baseManager = getManager((Class<? extends BaseManager>) type);

                    if (baseManager == null) {
                        throw new RuntimeException(type.getSimpleName() + " 管理类还未初始化！");
                    }

                    if (!field.isAccessible())
                        field.setAccessible(true);

                    try {
                        field.set(object, baseManager);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }

            aClass = aClass.getSuperclass();
        }
    }

    protected void registerManager(List<BaseManager> lists) {
          lists.add(new UserManager());
          lists.add(new SettingManager());
//        lists.add(new CacheManager());
//        lists.add(new SellerManager());
          lists.add(new VersionManager());

    }

    public Handler getHandler() {
        return handler;
    }

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.FIELD})
    public @interface Manager {
    }

    @Override
    public void onTerminate() {
        super.onTerminate();
    }



}